package jsoniters

import (
	"fmt"
	jsoniter "github.com/json-iterator/go"
	"github.com/modern-go/reflect2"
	"reflect"
	"strings"
	"time"
	"unsafe"
)

type Person struct {
	Name     string    `json:"name"`
	Age      int       `json:"age"`
	Birthday time.Time `json:"birthday"`
}

func RunSimple() {
	var json = jsoniter.Config{}.Froze()

	data := []byte(`{"name":"john doe","age":30}`)

	var p Person
	err := json.Unmarshal(data, &p)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Printf("%+v\n", p) // 输出: {Name:JOHN DOE Age:30}
}

type UpperString string

func decodeUpperString(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
	str := iter.ReadString()
	*((*UpperString)(ptr)) = UpperString(strings.ToUpper(str))
}

func RunCustomDecoder() {

	// 注册时间处理
	jsoniter.RegisterTypeDecoderFunc(reflect2.TypeOf(time.Time{}).String(), func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
		//t, err := time.Parse(time.RFC3339, iter.ReadString())
		t, err := time.Parse(YYYY_MM_DD_HH_MM_SS, iter.ReadString())
		if err != nil {
			iter.ReportError("decode time", err.Error())
			return
		}
		*(*time.Time)(ptr) = t
	})

	jsoniter.RegisterTypeEncoderFunc(reflect2.TypeOf(time.Time{}).String(), func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
		t := *(*time.Time)(ptr)

		stream.WriteString(t.Format(YYYY_MM_DD_HH_MM_SS))

	}, func(ptr unsafe.Pointer) bool {
		t := *(*time.Time)(ptr)
		return t.IsZero()
	})

	var json = jsoniter.Config{}.Froze()

	data := []byte(`{"name":"john doe","age":30,"birthday":"2006-01-02 15:04:05"}`)

	var p Person
	err := json.Unmarshal(data, &p)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	bs, err := json.Marshal(&p)
	if err != nil {
		fmt.Println("Error2:", err)
		return
	}

	fmt.Printf("%+v\n", p)         // 输出: {Name:john doe Age:30 Birthday:2006-01-02 15:04:05 +0000 UTC}
	fmt.Printf("%s\n", string(bs)) // 输出: {"name":"john doe","age":30,"birthday":"2006-01-02 15:04:05"}

}

func RunCustomEncoder() {

	jsoniter.RegisterFieldEncoderFunc(reflect2.TypeOf(Person{}).String(), "Birthday", func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
		t := *((*time.Time)(ptr))
		stream.WriteString(t.Format("2006-01-02"))
		//stream.WriteRaw()
	}, func(p unsafe.Pointer) bool {
		return reflect.ValueOf(p).IsNil() || IsStructZero(*(*time.Time)(p))
	})

	var json = jsoniter.Config{}.Froze()

	p2 := Person{
		Name: "john doe",
		Age:  30,
		//Birthday: time.Now(),
	}
	bytes, err := json.Marshal(p2)
	if err != nil {
		fmt.Println("Error:", err)
	}

	fmt.Println(IsStructZero(p2.Birthday))

	fmt.Printf("%s\n", string(bytes)) // 输出: {Name:JOHN DOE Age:30}

}
